feat(getRandomUser): endpoint get Random user#15
Conversation
d25827e to
faf4647
Compare
|
C'est un très bon premier jet en tout cas, bien joué 👍🏻 |
There was a problem hiding this comment.
Pull request overview
This pull request implements a new REST API endpoint to fetch random users from the external Random User API (https://randomuser.me/) and persist them to a PostgreSQL database. The implementation follows Clean Architecture principles with clear separation between presentation, domain, and data layers, and includes Docker Compose configuration for local database setup.
Changes:
- Added GET /user/random endpoint that fetches and saves random users with configurable count parameter (default: 500)
- Implemented PostgreSQL database integration with Spring Data JDBC and schema initialization
- Integrated Retrofit HTTP client to consume the external Random User API
- Added comprehensive Swagger/OpenAPI documentation for the new endpoint
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 18 comments.
Show a summary per file
| File | Description |
|---|---|
| src/main/resources/schema.sql | Database schema for user_entity table with fields for user data |
| src/main/resources/application.properties | Added database connection configuration and Random User API URL |
| src/main/java/.../presentation/handlers/UserHandler.java | REST controller handler implementing the getRandomUsers endpoint |
| src/main/java/.../presentation/controllers/UserController.java | Interface defining the API contract with Swagger annotations |
| src/main/java/.../domain/usecases/FetchAndSaveRandomUsersUseCase.java | Business logic for fetching from API and saving to database |
| src/main/java/.../domain/services/UserService.java | Domain service interface for user persistence operations |
| src/main/java/.../domain/entities/UserEntity.java | Domain entity representing a user |
| src/main/java/.../data/sources/RandomUserRetrofitClient.java | Retrofit client configuration for external API calls |
| src/main/java/.../data/sources/RandomUserApi.java | Retrofit API interface for Random User endpoints |
| src/main/java/.../data/services/UserServiceImpl.java | Implementation of UserService using Spring Data repository |
| src/main/java/.../data/repositories/UserRepository.java | Spring Data JDBC repository for UserEntity |
| src/main/java/.../data/models/RandomUserResultDAO.java | DAO for individual user result from API |
| src/main/java/.../data/models/RandomUserResponseDAO.java | DAO for API response wrapper |
| src/main/java/.../data/models/RandomUserPictureDAO.java | DAO for user picture data |
| src/main/java/.../data/models/RandomUserNameDAO.java | DAO for user name data |
| src/main/java/.../data/models/RandomUserInfoDAO.java | DAO for API metadata |
| src/main/java/.../data/converters/UserConverter.java | Converts between DAO and domain entity |
| pom.xml | Added Retrofit converter-gson dependency and enabled spring-boot-starter-data-jdbc |
| docker-compose.yaml | PostgreSQL container configuration with schema initialization |
| README.md | Updated checklist marking the endpoint implementation as complete |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
PiotrFLEURY
left a comment
There was a problem hiding this comment.
Quelques modifications à prévoir
49df95c to
3edd2ca
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 32 changed files in this pull request and generated 12 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…etter encapsulation
732ed1c to
5bdb66c
Compare
df73944 to
86b3bac
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 32 out of 33 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…plication context validation
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 32 out of 33 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 32 out of 33 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ller to use UserEntity directly
…ations for clarity
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 30 out of 31 changed files in this pull request and generated 9 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| spring.application.name=spring_boot_java_random_user | ||
| # Swagger UI custom path | ||
| springdoc.swagger-ui.path=/api | ||
| # URL for Random User API | ||
| randomuser.api.base-url=https://dummyjson.com/ | ||
|
|
||
| spring.datasource.url=jdbc:postgresql://localhost:${POSTGRES_PORT}/${POSTGRES_DB} | ||
| spring.datasource.username=${POSTGRES_USER} | ||
| spring.datasource.password=${POSTGRES_PASSWORD} No newline at end of file |
There was a problem hiding this comment.
This file is committed to the repository, but .gitignore also ignores application-local.properties. If this file is meant to be developer-specific, it should not be committed (provide a .template instead). If it is meant to be an example/default, remove the ignore rule so updates are tracked consistently.
| @Test | ||
| @DisplayName("Should handle null response gracefully") | ||
| void shouldHandleNullResponseGracefully() throws IOException { | ||
| when(randomUserProvider.fetchRandomUsers(1)).thenReturn(null); | ||
| when(userService.saveAll(null)).thenReturn(null); | ||
| List<UserEntity> result = useCase.execute(1); | ||
| assertNull(result); | ||
| } |
There was a problem hiding this comment.
This test enforces that a null provider response should be handled and propagated as null. In production, RandomUserProviderImpl throws when the response/users list is null and UserServiceImpl.saveAll NPEs on null input, so this test is currently encoding behavior that the real implementation does not support. Please either remove/update the test or update the production code to explicitly support null (preferably by returning an empty list or throwing a clear exception).
| List<UserEntity> fetched = List.of(new UserEntity( | ||
| 1L, "male", "John", "Doe", "Mr", "john@doe.com", "1234", "pic.jpg", "FR" | ||
| )); when(randomUserProvider.fetchRandomUsers(2)).thenReturn(fetched); | ||
| when(userService.saveAll(fetched)).thenReturn(fetched); |
There was a problem hiding this comment.
Minor readability issue: the stub setup when(randomUserProvider.fetchRandomUsers(2))... is on the same line as the List.of(...) closing. Please put it on a new properly-indented line so the test is easier to read/maintain.
| - [ ] [Add this endpoint PUT /user/{id}](https://github.com/XPEHO/spring_boot_java_random_user/issues/9) | ||
| - [ ] [Add this endpoint DELETE /user/{id}](https://github.com/XPEHO/spring_boot_java_random_user/issues/10) | ||
| - [ ] [Add this endpoint POST /user](https://github.com/XPEHO/spring_boot_java_random_user/issues/11) | ||
| - [X] [Add this endpoint get /user/random](https://github.com/XPEHO/spring_boot_java_random_user/issues/5) |
There was a problem hiding this comment.
The README marks GET /user/random as implemented, but the only controller mapping introduced is /random-users (see @RequestMapping("/random-users")). Please update either the API route or this checklist entry so they match.
| - [X] [Add this endpoint get /user/random](https://github.com/XPEHO/spring_boot_java_random_user/issues/5) | |
| - [X] [Add this endpoint get /random-users](https://github.com/XPEHO/spring_boot_java_random_user/issues/5) |
| public class RandomUserNameDAO { | ||
| private String title; | ||
| private String first; | ||
| private String last; | ||
|
|
||
| public String getTitle() { return title; } |
There was a problem hiding this comment.
This API model class appears unused in the production code (only referenced by its own test). If the project is now using the DummyJSON /users schema (flat firstName/lastName/image), consider removing this class (and its test) to avoid dead code, or wire it into the actual API response model if it's still needed.
| } | ||
|
|
||
| @Override | ||
| public List<UserEntity> saveAll(List<UserEntity> users) { |
There was a problem hiding this comment.
saveAll will throw a NullPointerException if users is null (users.stream()). Either enforce non-null at the service boundary (e.g., validate and throw an IllegalArgumentException) or make this method null-safe (e.g., treat null as an empty list) so the contract is explicit and consistent with callers/tests.
| public List<UserEntity> saveAll(List<UserEntity> users) { | |
| public List<UserEntity> saveAll(List<UserEntity> users) { | |
| if (users == null) { | |
| throw new IllegalArgumentException("users must not be null"); | |
| } |
| when(randomUserApi.getRandomUsers(count)).thenReturn(call); | ||
| when(call.execute()).thenReturn(Response.success(null)); | ||
| assertThrows(IOException.class, () -> provider.fetchRandomUsers(count)); | ||
| } |
There was a problem hiding this comment.
RandomUserProviderImpl has an explicit branch that throws when response.body() is non-null but response.body().getUsers() is null, but there is no test covering that branch. Please add a test case where Response.success(responseObj) is returned with responseObj.setUsers(null) and assert that an IOException is thrown.
| } | |
| } | |
| @Test | |
| @DisplayName("Should throw IOException when response body has null users list") | |
| void shouldThrowIOExceptionWhenResponseBodyHasNullUsersList() throws IOException { | |
| int count = 1; | |
| RandomUserResponse responseObj = new RandomUserResponse(); | |
| responseObj.setUsers(null); | |
| when(randomUserApi.getRandomUsers(count)).thenReturn(call); | |
| when(call.execute()).thenReturn(Response.success(responseObj)); | |
| assertThrows(IOException.class, () -> provider.fetchRandomUsers(count)); | |
| } |
| public class RandomUserPictureDAO { | ||
| private String medium; | ||
|
|
||
| public String getMedium() { |
There was a problem hiding this comment.
This API model class appears unused in the production code (only referenced by its own test). If the project is now using the DummyJSON /users schema (single image field), consider removing this class (and its test) to avoid dead code, or integrate it into the API response model if it is still intended to be used.
| @RequestMapping("/random-users") | ||
| @Tag(name = "User", description = "Endpoints for random user generation") |
There was a problem hiding this comment.
The endpoint is mapped to /random-users, but the README todo checklist (issue #5) states the implemented endpoint should be GET /user/random. Either update the controller mapping to match the documented/expected route, or update the README/issue references so the API contract is consistent.




Swagger :

Archi du projet:
